#ifndef GRIDPAGENUMBERSYSTEM_H
#define GRIDPAGENUMBERSYSTEM_H

#include <QPointF>
#include <QRectF>
#include <QMap>
#include <QDebug>
#include "pagepositionsystem.h"

/**
 * 3×3网格页码调节系统
 *
 * 基于Martin Fowler重构原则设计的简化页码位置调节系统。
 * 将复杂的精细调整机制简化为直观的网格步进调节。
 *
 * 设计理念：
 * - 系统预设位置作为网格中心点
 * - 每个位置有3×3共9个可选状态
 * - 每个网格步进代表10mm偏移
 * - 消除Magic Number，使用枚举驱动
 */
class GridPageNumberSystem
{
public:
    /**
     * 网格步进枚举 - 替代硬编码偏移值
     */
    enum class GridStep {
        Negative = -1,  // -10mm
        Center = 0,     // 0mm (系统预设位置)
        Positive = 1    // +10mm
    };

    /**
     * 网格状态结构 - 每个位置的当前网格状态
     */
    struct GridState {
        GridStep horizontalStep = GridStep::Center;
        GridStep verticalStep = GridStep::Center;

        /**
         * 转换为实际毫米偏移量
         */
        QPointF toMillimeterOffset() const {
            return QPointF(
                static_cast<int>(horizontalStep) * GRID_STEP_MM,
                static_cast<int>(verticalStep) * GRID_STEP_MM
            );
        }

        /**
         * 从毫米偏移量创建网格状态
         */
        static GridState fromMillimeterOffset(const QPointF& offset) {
            GridState state;
            state.horizontalStep = snapToGridStep(offset.x());
            state.verticalStep = snapToGridStep(offset.y());
            return state;
        }

        /**
         * 检查是否为网格中心位置
         */
        bool isCenter() const {
            return horizontalStep == GridStep::Center &&
                   verticalStep == GridStep::Center;
        }

        /**
         * 重置到网格中心
         */
        void reset() {
            horizontalStep = GridStep::Center;
            verticalStep = GridStep::Center;
        }

        /**
         * 相等比较
         */
        bool operator==(const GridState& other) const {
            return horizontalStep == other.horizontalStep &&
                   verticalStep == other.verticalStep;
        }

        bool operator!=(const GridState& other) const {
            return !(*this == other);
        }
    };

    /**
     * 构造函数
     */
    GridPageNumberSystem();

    /**
     * 设置指定位置的网格状态
     */
    void setGridState(PagePositionSystem::Position position, const GridState& gridState);

    /**
     * 获取指定位置的网格状态
     */
    GridState getGridState(PagePositionSystem::Position position) const;

    /**
     * 计算考虑网格偏移后的实际页码位置
     */
    QPointF calculateGridPosition(const QRectF& pageRect,
                                 PagePositionSystem::Position position) const;

    /**
     * 计算指定位置在特定网格状态下的坐标
     */
    QPointF calculateGridPosition(const QRectF& pageRect,
                                 PagePositionSystem::Position position,
                                 const GridState& gridState) const;

    /**
     * 获取指定位置的所有可达网格点坐标（用于绘制提示）
     */
    QList<QPointF> getReachableGridPoints(const QRectF& pageRect,
                                         PagePositionSystem::Position position) const;

    /**
     * 将像素坐标吸附到最近的网格点
     */
    GridState snapToNearestGrid(const QRectF& pageRect,
                               PagePositionSystem::Position position,
                               const QPointF& pixelPosition) const;

    /**
     * 重置指定位置到网格中心
     */
    void resetToCenter(PagePositionSystem::Position position);

    /**
     * 重置所有位置到网格中心
     */
    void resetAllToCenter();

    /**
     * 检查网格状态是否在有效范围内
     */
    static bool isValidGridState(const GridState& gridState);

    /**
     * 网格步进转换为毫米值
     */
    static double gridStepToMillimeters(GridStep step);

    /**
     * 毫米值转换为网格步进（吸附到最近值）
     */
    static GridStep millimetersToGridStep(double mm);

private:
    /**
     * 网格常量
     */
    static constexpr double GRID_STEP_MM = 10.0;  // 每个网格步进10mm

    /**
     * 存储每个预设位置的网格状态
     */
    QMap<PagePositionSystem::Position, GridState> m_gridStates;

    /**
     * 吸附毫米值到网格步进
     */
    static GridStep snapToGridStep(double mm);

    /**
     * 计算居中位置的特殊处理（水平围绕页面中线）
     */
    QPointF calculateCenterConstrainedPosition(const QRectF& pageRect,
                                              PagePositionSystem::Position position,
                                              const GridState& gridState) const;

    /**
     * 计算四角位置的标准处理
     */
    QPointF calculateCornerConstrainedPosition(const QRectF& pageRect,
                                              PagePositionSystem::Position position,
                                              const GridState& gridState) const;
};

/**
 * QDebug支持 - 便于调试输出
 */
inline QDebug operator<<(QDebug debug, GridPageNumberSystem::GridStep step)
{
    switch (step) {
        case GridPageNumberSystem::GridStep::Negative: debug << "GridStep::Negative(-10mm)"; break;
        case GridPageNumberSystem::GridStep::Center:   debug << "GridStep::Center(0mm)"; break;
        case GridPageNumberSystem::GridStep::Positive: debug << "GridStep::Positive(+10mm)"; break;
    }
    return debug;
}

inline QDebug operator<<(QDebug debug, const GridPageNumberSystem::GridState& state)
{
    debug.nospace() << "GridState(h:" << state.horizontalStep
                   << ", v:" << state.verticalStep << ")";
    return debug.space();
}

#endif // GRIDPAGENUMBERSYSTEM_H